<!DOCTYPE html>
<html><head>
<title>将Cryptoauthlib设置为Linux系统的PKCS11提供程序</title>




<meta charset="utf-8">
<meta name="X-UA-Compatible" content="IE=edge">
<meta name="google-site-verification" content="">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<meta content="telephone=no" name="format-detection">
<meta name="description" content="本文介绍如何构建和安装Cryptoauthlib、并且配置为pkcs11提供者。适用于带有包管理器的常用Linux系统。">
<meta name="renderer" content="webkit">
<meta name="theme-color" content="#ffffff">











<link type="text/css" rel="stylesheet" href="../../vendor/css/bootstrap.min.css">
<script src="../../vendor/js/vue.min.js" ></script>









<link rel="stylesheet" href="https://flyerink.gitee.io/scss/journal.min.3f72a5fc8f5b5dd732a4b476aced0eece2156958d9d414316494ddb10593ddf7.css" integrity="sha256-P3Kl/I9bXdcypLR2rO0O7OIVaVjZ1BQxZJTdsQWT3fc=" media="screen">



<link rel="stylesheet" href="https://flyerink.gitee.io/scss/dark-mode.min.c0082f0b082177f6fb3768ff91439a097de49689bd26f4d49f76d94ebb81e02d.css" integrity="sha256-wAgvCwghd/b7N2j/kUOaCX3klom9JvTUn3bZTruB4C0=" media="screen">


<script src="../../js/loadCSS.js"></script>
<script>
  loadCSS("https://fonts.googleapis.com/css?family=Fira+Mono|Material+Icons");
</script>




  
    <script src="../../js/toc.js"></script>
  














</head>
<body>
    	<div id="app"><div ref="sideContainer" class="side-container">
    
    <a class="a-block nav-head false" href="https://flyerink.gitee.io/">
    
        <div class="nav-title">
            飞墨空间·笔记
        </div>
        
        <div class="nav-subtitle">
            FlyerInk的博客
        </div>
        
    </a>

    <div class="nav-link-list">
        
        
            
            
            
                
            
            
            
            <a class="a-block nav-link-item active" href="../../post">
                文章
            </a>
            
        
            
            
            
            
            
            <a class="a-block nav-link-item false" href="../../categories">
                分类
            </a>
            
        
            
            
            
            
            
            <a class="a-block nav-link-item false" href="../../tags">
                标签
            </a>
            
        
            
            
            
            
            
            <a class="a-block nav-link-item false" href="../../post/about">
                关于我
            </a>
            
        
    </div>

    

    <div class="nav-footer">
        
Hugo Theme <a href="https://github.com/amazingrise/hugo-theme-diary">Diary</a> By <a href="https://amazingrise.net">Rise</a>
<br>
移植自 <a href="https://mak1t0.cc/" target="_blank" rel="noreferrer noopener">Makito</a>'s <a href="https://github.com/SumiMakito/hexo-theme-journal/" target="_blank" rel="noreferrer noopener">Journal.</a> <br>
<br>

&copy;
	
	Copyright (c) 2021, Flyerink Wang
	

    </div>
    
</div><div ref="extraContainer" class="extra-container">
    
    
    <div class="toc animated-visibility" :class="{ invisible: scrollY <= 140 }">


	<div class="toc-content">
	
		
		
		
		<center>- 目录 -</center>
		
		
		<ul>
			
				
				
					
						
						
						
						
							
								
									<ul>
								
							
						
						
							<li>
								<a href="#%e6%9b%b4%e6%96%b0%e7%b3%bb%e7%bb%9f%e7%9a%84libp11%e6%9c%80%e4%bd%8e%e7%89%88%e6%9c%ac%e6%98%af0410" onclick="onNavClick(`#更新系统的libp11最低版本是0410-nav`)" id="更新系统的libp11最低版本是0410-nav">
									更新系统的libp11,最低版本是0.4.10
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
							
								
									<ul>
								
							
								
									<ul>
								
							
						
						
							<li>
								<a href="#%e5%ae%89%e8%a3%85%e7%b3%bb%e7%bb%9f%e7%9a%84%e6%9e%84%e5%bb%ba%e4%be%9d%e8%b5%96%e5%ba%93" onclick="onNavClick(`#安装系统的构建依赖库-nav`)" id="安装系统的构建依赖库-nav">
									安装系统的构建依赖库:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e8%8e%b7%e5%8f%96%e6%9c%80%e6%96%b0%e7%89%88%e6%9c%ac%e7%9a%84libp11" onclick="onNavClick(`#获取最新版本的libp11-nav`)" id="获取最新版本的libp11-nav">
									获取最新版本的libp11
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
							
								</ul>
							
								</ul>
							
						
						
						
							<li>
								<a href="#%e6%9e%84%e5%bb%ba%e5%92%8c%e5%ae%89%e8%a3%85%e6%94%af%e6%8c%81pkcs11%e7%9a%84cryptoauthlib" onclick="onNavClick(`#构建和安装支持pkcs11的cryptoauthlib-nav`)" id="构建和安装支持pkcs11的cryptoauthlib-nav">
									构建和安装支持PKCS11的cryptoauthlib
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
							
								
									<ul>
								
							
								
									<ul>
								
							
						
						
							<li>
								<a href="#%e5%ae%89%e8%a3%85%e7%b3%bb%e7%bb%9f%e7%9a%84%e6%9e%84%e5%bb%ba%e4%be%9d%e8%b5%96%e5%ba%93libudev-dev" onclick="onNavClick(`#安装系统的构建依赖库libudev-dev-nav`)" id="安装系统的构建依赖库libudev-dev-nav">
									安装系统的构建依赖库libudev-dev:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e8%8e%b7%e5%8f%96%e6%94%af%e6%8c%81pkcs11%e7%9a%84cryptoauthlib%e6%9c%80%e6%96%b0%e7%89%88%e6%9c%ac" onclick="onNavClick(`#获取支持pkcs11的cryptoauthlib最新版本-nav`)" id="获取支持pkcs11的cryptoauthlib最新版本-nav">
									获取支持PKCS11的cryptoauthlib最新版本
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e4%bd%bf%e7%94%a8cmake%e5%b7%a5%e5%85%b7%e7%bc%96%e8%af%91cryptoauthlib%e5%ba%93" onclick="onNavClick(`#使用cmake工具编译cryptoauthlib库-nav`)" id="使用cmake工具编译cryptoauthlib库-nav">
									使用cmake工具编译Cryptoauthlib库:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e7%bc%96%e8%af%91" onclick="onNavClick(`#编译-nav`)" id="编译-nav">
									编译:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e5%ae%89%e8%a3%85" onclick="onNavClick(`#安装-nav`)" id="安装-nav">
									安装:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
							
								</ul>
							
								</ul>
							
						
						
						
							<li>
								<a href="#%e9%85%8d%e7%bd%aecryptoauthlib-pkcs11%e5%ba%93" onclick="onNavClick(`#配置cryptoauthlib-pkcs11库-nav`)" id="配置cryptoauthlib-pkcs11库-nav">
									配置cryptoauthlib PKCS11库
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
							
								
									<ul>
								
							
								
									<ul>
								
							
						
						
							<li>
								<a href="#cryptoauthlibconf" onclick="onNavClick(`#cryptoauthlibconf-nav`)" id="cryptoauthlibconf-nav">
									cryptoauthlib.conf
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#slotconftmpl" onclick="onNavClick(`#slotconftmpl-nav`)" id="slotconftmpl-nav">
									slot.conf.tmpl
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#interface-%e6%8e%a5%e5%8f%a3" onclick="onNavClick(`#interface-接口-nav`)" id="interface-接口-nav">
									interface 接口
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#freeslots-%e7%a9%ba%e9%97%b2%e7%9a%84%e6%a7%bd" onclick="onNavClick(`#freeslots-空闲的槽-nav`)" id="freeslots-空闲的槽-nav">
									freeslots 空闲的槽
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
							
								</ul>
							
								</ul>
							
						
						
						
							<li>
								<a href="#%e4%bd%bf%e7%94%a8-p11-kit-proxy" onclick="onNavClick(`#使用-p11-kit-proxy-nav`)" id="使用-p11-kit-proxy-nav">
									使用 p11-kit-proxy
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e4%b8%8d%e4%bd%bf%e7%94%a8-p11-kit-proxy" onclick="onNavClick(`#不使用-p11-kit-proxy-nav`)" id="不使用-p11-kit-proxy-nav">
									不使用 p11-kit-proxy
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e6%b5%8b%e8%af%95" onclick="onNavClick(`#测试-nav`)" id="测试-nav">
									测试
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e5%9c%a8linux%e4%b8%ad%e4%bd%bf%e7%94%a8hid-kit" onclick="onNavClick(`#在linux中使用hid-kit-nav`)" id="在linux中使用hid-kit-nav">
									在Linux中使用HID KIT
								</a>
							</li>
						
						
					
				
			
		</ul>
	</div>

</div>
    
    <div class="pagination">
        <a id="globalBackToTop" class="pagination-action animated-visibility" href="#top" :class="{ invisible: scrollY == 0 }">
            <i class="material-icons pagination-action-icon">
                keyboard_arrow_up
            </i>
        </a>
        
        <a class="pagination-action" v-on:click="toggleDarkMode">
            <i class="material-icons pagination-action-icon" v-if="isDarkMode">
                brightness_4
            </i>
            <i class="material-icons pagination-action-icon" v-else="isDarkMode">
                brightness_7
            </i>
        </a>
        
        
    </div>
</div>
<div class="single-column-drawer-container" ref="drawer"
     v-bind:class="{ 'single-column-drawer-container-active': isDrawerOpen }">
    <div class="drawer-content">
        <div class="drawer-menu">
            
            
            
                
                
                
                    
                
                
                
                <a class="a-block drawer-menu-item active" href="../../post">
                    文章
                </a>
                
            
                
                
                
                
                
                <a class="a-block drawer-menu-item false" href="../../categories">
                    分类
                </a>
                
            
                
                
                
                
                
                <a class="a-block drawer-menu-item false" href="../../tags">
                    标签
                </a>
                
            
                
                
                
                
                
                <a class="a-block drawer-menu-item false" href="../../post/about">
                    关于我
                </a>
                
            
            
            <div class="toc">


	<div class="toc-content">
	
		
		
		
		<center>- 目录 -</center>
		
		
		<ul>
			
				
				
					
						
						
						
						
							
								
									<ul>
								
							
						
						
							<li>
								<a href="#%e6%9b%b4%e6%96%b0%e7%b3%bb%e7%bb%9f%e7%9a%84libp11%e6%9c%80%e4%bd%8e%e7%89%88%e6%9c%ac%e6%98%af0410" onclick="onNavClick(`#更新系统的libp11最低版本是0410-nav`)" id="更新系统的libp11最低版本是0410-nav">
									更新系统的libp11,最低版本是0.4.10
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
							
								
									<ul>
								
							
								
									<ul>
								
							
						
						
							<li>
								<a href="#%e5%ae%89%e8%a3%85%e7%b3%bb%e7%bb%9f%e7%9a%84%e6%9e%84%e5%bb%ba%e4%be%9d%e8%b5%96%e5%ba%93" onclick="onNavClick(`#安装系统的构建依赖库-nav`)" id="安装系统的构建依赖库-nav">
									安装系统的构建依赖库:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e8%8e%b7%e5%8f%96%e6%9c%80%e6%96%b0%e7%89%88%e6%9c%ac%e7%9a%84libp11" onclick="onNavClick(`#获取最新版本的libp11-nav`)" id="获取最新版本的libp11-nav">
									获取最新版本的libp11
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
							
								</ul>
							
								</ul>
							
						
						
						
							<li>
								<a href="#%e6%9e%84%e5%bb%ba%e5%92%8c%e5%ae%89%e8%a3%85%e6%94%af%e6%8c%81pkcs11%e7%9a%84cryptoauthlib" onclick="onNavClick(`#构建和安装支持pkcs11的cryptoauthlib-nav`)" id="构建和安装支持pkcs11的cryptoauthlib-nav">
									构建和安装支持PKCS11的cryptoauthlib
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
							
								
									<ul>
								
							
								
									<ul>
								
							
						
						
							<li>
								<a href="#%e5%ae%89%e8%a3%85%e7%b3%bb%e7%bb%9f%e7%9a%84%e6%9e%84%e5%bb%ba%e4%be%9d%e8%b5%96%e5%ba%93libudev-dev" onclick="onNavClick(`#安装系统的构建依赖库libudev-dev-nav`)" id="安装系统的构建依赖库libudev-dev-nav">
									安装系统的构建依赖库libudev-dev:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e8%8e%b7%e5%8f%96%e6%94%af%e6%8c%81pkcs11%e7%9a%84cryptoauthlib%e6%9c%80%e6%96%b0%e7%89%88%e6%9c%ac" onclick="onNavClick(`#获取支持pkcs11的cryptoauthlib最新版本-nav`)" id="获取支持pkcs11的cryptoauthlib最新版本-nav">
									获取支持PKCS11的cryptoauthlib最新版本
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e4%bd%bf%e7%94%a8cmake%e5%b7%a5%e5%85%b7%e7%bc%96%e8%af%91cryptoauthlib%e5%ba%93" onclick="onNavClick(`#使用cmake工具编译cryptoauthlib库-nav`)" id="使用cmake工具编译cryptoauthlib库-nav">
									使用cmake工具编译Cryptoauthlib库:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e7%bc%96%e8%af%91" onclick="onNavClick(`#编译-nav`)" id="编译-nav">
									编译:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e5%ae%89%e8%a3%85" onclick="onNavClick(`#安装-nav`)" id="安装-nav">
									安装:
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
							
								</ul>
							
								</ul>
							
						
						
						
							<li>
								<a href="#%e9%85%8d%e7%bd%aecryptoauthlib-pkcs11%e5%ba%93" onclick="onNavClick(`#配置cryptoauthlib-pkcs11库-nav`)" id="配置cryptoauthlib-pkcs11库-nav">
									配置cryptoauthlib PKCS11库
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
							
								
									<ul>
								
							
								
									<ul>
								
							
						
						
							<li>
								<a href="#cryptoauthlibconf" onclick="onNavClick(`#cryptoauthlibconf-nav`)" id="cryptoauthlibconf-nav">
									cryptoauthlib.conf
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#slotconftmpl" onclick="onNavClick(`#slotconftmpl-nav`)" id="slotconftmpl-nav">
									slot.conf.tmpl
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#interface-%e6%8e%a5%e5%8f%a3" onclick="onNavClick(`#interface-接口-nav`)" id="interface-接口-nav">
									interface 接口
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#freeslots-%e7%a9%ba%e9%97%b2%e7%9a%84%e6%a7%bd" onclick="onNavClick(`#freeslots-空闲的槽-nav`)" id="freeslots-空闲的槽-nav">
									freeslots 空闲的槽
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
							
								</ul>
							
								</ul>
							
						
						
						
							<li>
								<a href="#%e4%bd%bf%e7%94%a8-p11-kit-proxy" onclick="onNavClick(`#使用-p11-kit-proxy-nav`)" id="使用-p11-kit-proxy-nav">
									使用 p11-kit-proxy
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e4%b8%8d%e4%bd%bf%e7%94%a8-p11-kit-proxy" onclick="onNavClick(`#不使用-p11-kit-proxy-nav`)" id="不使用-p11-kit-proxy-nav">
									不使用 p11-kit-proxy
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e6%b5%8b%e8%af%95" onclick="onNavClick(`#测试-nav`)" id="测试-nav">
									测试
								</a>
							</li>
						
						
					
				
			
				
				
					
						
						
						
						
						
							<li>
								<a href="#%e5%9c%a8linux%e4%b8%ad%e4%bd%bf%e7%94%a8hid-kit" onclick="onNavClick(`#在linux中使用hid-kit-nav`)" id="在linux中使用hid-kit-nav">
									在Linux中使用HID KIT
								</a>
							</li>
						
						
					
				
			
		</ul>
	</div>

</div>
            
        </div>
    </div>
</div>
<transition name="fade">
    <div v-bind:class="{ 'single-column-drawer-mask': mounted }" v-if="isDrawerOpen" v-on:click="toggleDrawer"></div>
</transition>
<nav ref="navBar" class="navbar sticky-top navbar-light single-column-nav-container">
    <div ref="navBackground" class="nav-background"></div>
    <div class="container container-narrow nav-content">
        <button id="nav_dropdown_btn" class="nav-dropdown-toggle" type="button" v-on:click="toggleDrawer">
            <i class="material-icons">
                menu
            </i>
        </button>
        <a ref="navTitle" class="navbar-brand" href="https://flyerink.gitee.io/">
            飞墨空间·笔记
        </a>
        
        <button type="button" class="nav-darkmode-toggle" v-on:click="toggleDarkMode">
            <i class="material-icons" v-if="isDarkMode">
                brightness_4
            </i>
            <i class="material-icons" v-else="isDarkMode">
                brightness_7
            </i>
        </button>
        
    </div>
</nav>
<div class="single-column-header-container" ref="pageHead"
     v-bind:style="{ transform: 'translateZ(0px) translateY('+.3*scrollY+'px)', opacity: 1-navOpacity }">
    <a href="https://flyerink.gitee.io/">
        <div class="single-column-header-title">飞墨空间·笔记</div>
        
        <div class="single-column-header-subtitle">FlyerInk的博客</div>
        

    </a>
</div>

            <div id="content">
<div ref="streamContainer" class="stream-container">
    <div class="post-list-container post-list-container-shadow">
        <div class="post">
            
            
            

            <div class="post-head-wrapper-text-only"
                
            >
                <div class="post-title">
                    将Cryptoauthlib设置为Linux系统的PKCS11提供程序
                    
                    <div class="post-subtitle">
                        本文介绍如何构建和安装Cryptoauthlib、并且配置为pkcs11提供者。适用于带有包管理器的常用Linux系统。
                    </div>
                    
                    <div class="post-meta">
                        
                        <time itemprop="datePublished">
                            2021-05-17 16:58
                        </time>
                        

                        
                            <i class="material-icons" style="">folder</i>
                                <a href="../../categories/">[安全芯片开发]</a>
                                &nbsp;
                        

                        
                            <i class="material-icons" style="">label</i>
                            
                                <a href="../../tags/cryptoauthlib">Cryptoauthlib</a>
                                &nbsp;
                            
                                <a href="../../tags/linux">Linux</a>
                                &nbsp;
                            
                        
                        
                    </div>
                </div>
            </div>
            
            <div class="post-body-wrapper">
                
                <div class="post-body" v-pre>
                
                    <p>这些说明用于将Cryptoauthlib构建、安装和配置为pkcs11提供者。</p>
<p>这些说明适用于带有包管理器的常用Linux系统。</p>
<h2 id="更新系统的libp11最低版本是0410">更新系统的libp11,最低版本是0.4.10</h2>
<h4 id="安装系统的构建依赖库">安装系统的构建依赖库:</h4>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell"><span style="color:#228b22"># Debian like systems</span>
$ sudo apt-get build-dep libengine-pkcs11-openssl1.1
</code></pre></div><div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell"><span style="color:#228b22"># RPM based systems</span>
$ yum-builddep engine-pkcs11
</code></pre></div><h4 id="获取最新版本的libp11">获取最新版本的libp11</h4>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ git clone https://github.com/OpenSC/libp11.git
</code></pre></div><ul>
<li>构建配置工具:</li>
</ul>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ <span style="color:#658b00">cd</span> libp11
$ ./bootstrap
$ ./configure
</code></pre></div><p>或者可以指定安装目标</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">  ./configure --prefix=/usr/local
</code></pre></div><ul>
<li>编译库:</li>
</ul>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ make
</code></pre></div><ul>
<li>安装库:</li>
</ul>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ sudo make install
</code></pre></div><h2 id="构建和安装支持pkcs11的cryptoauthlib">构建和安装支持PKCS11的cryptoauthlib</h2>
<h4 id="安装系统的构建依赖库libudev-dev">安装系统的构建依赖库libudev-dev:</h4>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell"><span style="color:#228b22"># Debian like systems</span>
$ sudo apt-get install cmake libudev-dev
$ sudo apt-get install libusb-1.0
</code></pre></div><div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell"><span style="color:#228b22"># RPM based systems</span>
$ yum install cmake
$ yum install libudev-devel
</code></pre></div><h4 id="获取支持pkcs11的cryptoauthlib最新版本">获取支持PKCS11的cryptoauthlib最新版本</h4>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ git clone --single-branch -b pkcs11 https://github.com/MicrochipTech/cryptoauthlib
$ git clone --single-branch -b pkcs11 https://gitee.com/flyerink/cryptoauthlib
</code></pre></div><h4 id="使用cmake工具编译cryptoauthlib库">使用cmake工具编译Cryptoauthlib库:</h4>
<p>这里选择的是KIT_HID方式连接芯片</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ <span style="color:#658b00">cd</span> cryptoauthlib
$ mkdir build | <span style="color:#658b00">cd</span> build
$ cmake -DBUILD_TESTS=ON -DATCA_PKCS11=ON -DATCA_HAL_I2C=OFF -DATCA_HAL_KIT_HID=ON -DATCA_HAL_KIT_CDC=OFF -DATCA_PRINTF=OFF ..
</code></pre></div><p>如果是使用I2C接口的话，可以使用下面的命令行：</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">cmake -DBUILD_TESTS=ON -DATCA_PKCS11=ON -DATCA_HAL_I2C=ON -DATCA_HAL_KIT_HID=OFF -DATCA_HAL_KIT_CDC=OFF -DATCA_PRINTF=OFF ..
</code></pre></div><p>编译选项的说明：</p>
<ul>
<li>BUILD_TESTS：这里已经把BUILD_TESTS打开了，会自动编译生成测试程序，对当前的硬件用命令行的方式访问。可以用来验证硬件是否有问题。</li>
<li>ATCA_PKCS11：我们是要编译用于PKCS11的链接库，必须打开。</li>
<li>ATCA_HAL_I2C：如果使用I2C的HAL驱动需要开启，通常是针对带有I2C接口的目标板。</li>
<li>DATCA_HAL_KIT_HID：使用USB-HID作为通信接口，通常Microchip提供的开发板都支持这种方式，包括DM320118, DM320109和AT88CK101等。</li>
<li>ATCA_HAL_KIT_CDC：用于USB To UART的开发板连接。</li>
<li>ATCA_PRINTF：如果想使用库中提供的atca_printf相关函数，可以把ATCA_PRINTF打开。</li>
</ul>
<h4 id="编译">编译:</h4>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ make
</code></pre></div><h4 id="安装">安装:</h4>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ sudo make install
</code></pre></div><h2 id="配置cryptoauthlib-pkcs11库">配置cryptoauthlib PKCS11库</h2>
<p>在默认情况下，下面几个文件会自动创建：</p>
<ul>
<li>/etc/cryptoauthlib/cryptoauthlib.conf</li>
</ul>
<pre><code># Cryptoauthlib Configuration File
filestore = /var/lib/cryptoauthlib
</code></pre><ul>
<li>/var/lib/cryptoauthlib/slot.conf.tmpl</li>
</ul>
<pre><code># Reserved Configuration for a device
# The objects in this file will be created and marked as undeletable
# These are processed in order. Configuration parameters must be comma
# delimited and may not contain spaces

interface = i2c,0xB0
freeslots = 1,2,3

# Slot 0 is the primary private key
object = private,device,0

# Slot 10 is the certificate data for the device's public key
#object = certificate,device,10

# Slot 12 is the intermedate/signer certificate data
#object = certificate,signer,12

# Slot 15 is a public key
object = public,root,15
</code></pre><h4 id="cryptoauthlibconf">cryptoauthlib.conf</h4>
<p>该文件提供了库的基本配置信息。唯一的变量是“filestore”，在这里，cryptoauthlib将找到设备特定的配置，并在这里存储来自pkcs11操作的目标文件。</p>
<h4 id="slotconftmpl">slot.conf.tmpl</h4>
<p>这是设备配置文件的模板，cryptoauthlib将使用该模板将设备及其资源映射到pkcs11 tokens和objects中。</p>
<p>设备文件必须命名为&lt;pkcs11_slot_number&gt;.conf</p>
<p>对于单个设备:</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ <span style="color:#658b00">cd</span> /var/lib/cryptoauthlib
$ cp slot.conf.tmpl 0.conf
</code></pre></div><p>然后编辑0.conf以匹配所使用的设备配置。</p>
<h4 id="interface-接口">interface 接口</h4>
<p>允许的值:&lsquo;hid&rsquo;， &lsquo;i2c&rsquo;
如果使用i2c，请用十六进制指定设备的地址。这是设备格式(高7位定义地址)，所以不会出现与i2cdetect地址相同的情况(低7位)</p>
<h4 id="freeslots-空闲的槽">freeslots 空闲的槽</h4>
<p>这是一个插槽列表，当使用创建新对象的pkcs11操作时，库可能会使用这些插槽。当库被初始化时，它将扫描&lt;pkcs11_slot_num&gt;.&lt;device_slot_num&gt;.conf格式的文件，该格式定义了使用该设备资源的对象。</p>
<h2 id="使用-p11-kit-proxy">使用 p11-kit-proxy</h2>
<p>这是一个可选步骤，但对于在系统中使用多个pkcs11库非常有用。
详细设置可以在<a href="https://p11-glue.github.io/p11-glue/p11-kit/manual/">p11-glue</a>中找到</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh"><span style="color:#228b22"># Debian like systems</span>
$ sudo apt-get install p11-kit
</code></pre></div><div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh"><span style="color:#228b22"># RPM based systems</span>
$ yum install p11-kit
</code></pre></div><ul>
<li>创建或编辑全局配置文件:/etc/pkcs11/pkcs11.conf</li>
</ul>
<pre><code># This setting controls whether to load user configuration from the
# ~/.config/pkcs11 directory. Possible values:
#    none: No user configuration
#    merge: Merge the user config over the system configuration (default)
#    only: Only user configuration, ignore system configuration
user-config: merge
</code></pre><ul>
<li>创建模块配置文件:
用户模块名(仅对单个用户可用):~/.config/pkcs11/modules/cryptoauthlib.module
全局模块名(对整个系统可用):/usr/share/p11-kit/modules/cryptoauthlib.module</li>
</ul>
<pre><code>module: /usr/lib/libcryptoauth.so
critical: yes
trust-policy: yes
managed: yes
log-calls: no
</code></pre><p>有关配置文件的详细信息，请参阅<a href="https://p11-glue.github.io/p11-glue/p11-kit/manual/pkcs11-conf.html">configuration documentation</a></p>
<h2 id="不使用-p11-kit-proxy">不使用 p11-kit-proxy</h2>
<p>OpenSSL(通过上面的libp11项目)和p11tool本身就支持p11-kit-proxy，因此在使用它时不需要额外的设置。如果没有使用p11-kit-proxy，则必须手动配置OpenSSL来使用libp11和cryptoauthlib</p>
<p>这需要编辑默认的openssl.cnf文件。要查找系统使用的文件，请运行以下命令:</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ openssl version -a | grep OPENSSLDIR:

OPENSSLDIR: <span style="color:#cd5555">&#34;/usr/lib/ssl&#34;</span>
</code></pre></div><p>这给出了编译openssl以查找openssl.cnf文件的默认路径</p>
<p>在本例中，要编辑的文件是/usr/lib/ssl/openssl.cnf</p>
<p>这一行必须放在顶部，在任何部分被定义之前:</p>
<pre><code>openssl_conf = openssl_init
</code></pre><p>这应该添加到文件的底部:</p>
<pre><code>[openssl_init]
engines=engine_section

[engine_section]
pkcs11 = pkcs11_section

[pkcs11_section]
engine_id = pkcs11
# Wherever the engine installed by libp11 is. For example it could be:
# /usr/lib/arm-linux-gnueabihf/engines-1.1/libpkcs11.so
#dynamic_path = /usr/lib/ssl/engines/libpkcs11.so 
dynamic_path = /usr/lib/x86_64-linux-gnu/engines-1.1/libpkcs11.so
MODULE_PATH = /usr/lib/libcryptoauth.so
init = 0
</code></pre><h2 id="测试">测试</h2>
<p>要使用p11tool必须安装gnutls-bin:</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell"><span style="color:#228b22"># Debian like systems</span>
$ sudo apt-get install gnutls-bin
</code></pre></div><div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell"><span style="color:#228b22"># RPM based systems</span>
$ yum install gnutls-utils
</code></pre></div><p><strong>注意</strong>: 如果不使用p11-kit-proxy，则必须在p11tool调用中指定提供程序:</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ p11tool --provider /usr/lib/libcryptoauth.so
</code></pre></div><ul>
<li>获取私钥的公钥(如上所述的0.conf文件定义):</li>
</ul>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ p11tool --export-pubkey <span style="color:#cd5555">&#34;pkcs11:token=0123EE;object=device;type=private&#34;</span>
warning: --login was not specified and it may be required <span style="color:#8b008b;font-weight:bold">for</span> this operation.
warning: no --outfile was specified and the public key will be printed on screen.
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9wzUq1EUAoNrG01rXYjNd35mxKuA
Ojw/klIrNEBciSLLOTLjs/gvFS7N8AFXDK18vpxxu6ykzF2LRd7RY8yEFw==
-----END PUBLIC KEY-----
</code></pre></div><p>对于TNGTLS, 序列号的最后一个字节是0x01，默认的是0xEE, token需要修改成012301，可以先列出全部的token</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ p11tool --list-all
warning: no token URL was provided <span style="color:#8b008b;font-weight:bold">for</span> this operation; the available tokens are:

pkcs11:model=p11-kit-trust;<span style="color:#00688b">manufacturer</span>=PKCS%2311%20Kit;<span style="color:#00688b">serial</span>=1;<span style="color:#00688b">token</span>=ca-certificates.crt
pkcs11:model=ATECC608A;<span style="color:#00688b">manufacturer</span>=Microchip%20Technology%20Inc;<span style="color:#00688b">serial</span>=42BCF333A8BE;<span style="color:#00688b">token</span>=<span style="color:#b452cd">012301</span>
</code></pre></div><p>从中可以找到TNGTLS的Token=012301.</p>
<p>运行下列命令导出公钥，需要输入PIN码：</p>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ p11tool --export-pubkey <span style="color:#cd5555">&#34;pkcs11:token=012301;object=device;type=private&#34;</span>
warning: --login was not specified and it may be required <span style="color:#8b008b;font-weight:bold">for</span> this operation.
warning: no --outfile was specified and the public key will be printed on screen.
Token <span style="color:#cd5555">&#39;012301&#39;</span> with URL <span style="color:#cd5555">&#39;pkcs11:model=ATECC608A;manufacturer=Microchip%20Technology%20Inc;serial=42BCF333A8BE;token=012301&#39;</span> requires user PIN
Enter PIN: 
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE942lHpjOLzt6tKqF0bew/nyCyVnL
h4Vwln6jvDKL/QaoatkdLuH0sCuqWxFEzNVfqQ7LKOoKp+8cSP5yE03aFA==
-----END PUBLIC KEY-----
</code></pre></div><ul>
<li>导出公钥并且用OpenSSL解码 Get the public key and decode it using OpenSSL</li>
</ul>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ p11tool --export-pubkey <span style="color:#cd5555">&#34;pkcs11:token=012301;object=device;type=private&#34;</span> | openssl pkey -pubin -text -noout
warning: --login was not specified and it may be required <span style="color:#8b008b;font-weight:bold">for</span> this operation.
warning: no --outfile was specified and the public key will be printed on screen.
Public-Key: (<span style="color:#b452cd">256</span> bit)
pub:
    04:f7:0c:d4:ab:51:14:02:83:6b:1b:4d:6b:5d:88:
    cd:77:7e:66:c4:ab:80:3a:3c:3f:92:52:2b:34:40:
    5c:89:22:cb:39:32:e3:b3:f8:2f:15:2e:cd:f0:01:
    57:0c:ad:7c:be:9c:71:bb:ac:a4:cc:5d:8b:45:de:
    d1:63:cc:84:17
ASN1 OID: prime256v1
NIST CURVE: P-256
</code></pre></div><ul>
<li>为私钥创建CSR</li>
</ul>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ openssl req -engine pkcs11 -key <span style="color:#cd5555">&#34;pkcs11:token=012301;object=device;type=private&#34;</span> -keyform engine -new -out new_device.csr -subj <span style="color:#cd5555">&#34;/CN=NEW CSR EXAMPLE&#34;</span>

engine <span style="color:#cd5555">&#34;pkcs11&#34;</span> set.

$ cat new_device.csr
-----BEGIN CERTIFICATE REQUEST-----
MIHVMHwCAQAwGjEYMBYGA1UEAwwPTkVXIENTUiBFWEFNUExFMFkwEwYHKoZIzj0C
AQYIKoZIzj0DAQcDQgAE9wzUq1EUAoNrG01rXYjNd35mxKuAOjw/klIrNEBciSLL
OTLjs/gvFS7N8AFXDK18vpxxu6ykzF2LRd7RY8yEF6AAMAoGCCqGSM49BAMCA0kA
MEYCIQDUPeLfPcOwtZxYJDYXPdl2UhpReVn6kK2lKCCX6byM8QIhAIfqfnggtcCi
W21xLAzabr8A4mHyfIIQ1ofYBg8QO9jZ
-----END CERTIFICATE REQUEST-----
</code></pre></div><ul>
<li>验证新创建的CSR</li>
</ul>
<div class="highlight"><pre style="background-color:#eed;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-Shell" data-lang="Shell">$ openssl req -in new_device.csr -verify -text -noout
verify OK
Certificate Request:
    Data:
        Version: <span style="color:#b452cd">1</span> (0x0)
        Subject: <span style="color:#00688b">CN</span> = NEW CSR EXAMPLE
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (<span style="color:#b452cd">256</span> bit)
                pub:
                    04:f7:0c:d4:ab:51:14:02:83:6b:1b:4d:6b:5d:88:
                    cd:77:7e:66:c4:ab:80:3a:3c:3f:92:52:2b:34:40:
                    5c:89:22:cb:39:32:e3:b3:f8:2f:15:2e:cd:f0:01:
                    57:0c:ad:7c:be:9c:71:bb:ac:a4:cc:5d:8b:45:de:
                    d1:63:cc:84:17
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        Attributes:
            a0:00
    Signature Algorithm: ecdsa-with-SHA256
         30:46:02:21:00:d4:3d:e2:df:3d:c3:b0:b5:9c:58:24:36:17:
         3d:d9:76:52:1a:51:79:59:fa:90:ad:a5:28:20:97:e9:bc:8c:
         f1:02:21:00:87:ea:7e:78:20:b5:c0:a2:5b:6d:71:2c:0c:da:
         6e:bf:00:e2:61:f2:7c:82:10:d6:87:d8:06:0f:10:3b:d8:d9
</code></pre></div><h2 id="在linux中使用hid-kit">在Linux中使用HID KIT</h2>
<p>默认情况下，当使用通过USB-HID进行通信的cryptoauthlib时，如果不使用sudo运行，它们对cryptoauthlib是不可用的。为了解决这个问题，建议通过将<a href="https://github.com/MicrochipTech/cryptoauthlib/blob/master/lib/hal/90-cryptohid.rules">90-cryptohid.rules</a>文件添加到/etc/udev/rules来更新<code>/etc/udev/rules.d</code>文件夹</p>
<pre><code>$ sudo cp cryptoauthlib/lib/hal/90-cryptohid.rules /etc/udev/rules.d
</code></pre>
                    
                    <HR width="100%" id="EOF">
		    <p style="color:#777;">最后修改于 2021-05-17</p>
                    
                </div>
            </div>
            
            
            <nav class="post-pagination">

                
                <a class="newer-posts">
			下一篇<br>已经到头啦。
                </a>
                
                
                
                <a class="older-posts" href="https://flyerink.gitee.io/post/%E5%9C%A8linux%E4%B8%8B%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91cryptoauthlib%E5%88%B0arm%E5%B9%B3%E5%8F%B0%E4%B8%8B/">
			上一篇<br>在Linux下交叉编译Cryptoauthlib到ARM平台下
                </a>
                
            </nav>
            <div class="post-comment-wrapper">
                










            </div>
        </div>
    </div>
</div>

            </div><div id="single-column-footer">
Hugo Theme <a href="https://github.com/amazingrise/hugo-theme-diary">Diary</a> By <a href="https://amazingrise.net">Rise</a>
<br>
移植自 <a href="https://mak1t0.cc/" target="_blank" rel="noreferrer noopener">Makito</a>'s <a href="https://github.com/SumiMakito/hexo-theme-journal/" target="_blank" rel="noreferrer noopener">Journal.</a> <br>
<br>

&copy;
	
	Copyright (c) 2021, Flyerink Wang
	
</div>
            </div>
    <script>
let app;

app = new Vue({
    el: '#app',
    data: {
        scrollY: 0,
        navOpacity: 0,
        isDrawerOpen: false,
        mounted: false,
        isDarkMode: false
    },
    methods: {
            sgn(t, x) {
                let k = 1. / (1. - 2 * t);
                if (x <= t) return 0;
                else if (x >= 1 - t) return 1;
                else {
                    return k * (x - t);
                }
            },
            handleScroll() {
                this.scrollY = window.scrollY;
                this.navOpacity = this.sgn(.0, Math.min(1, Math.max(0, window.scrollY / (this.pageHeadHeight() - this.navBarHeight() * 0.8))));
                const {navBar, navBackground, navTitle, extraContainer, streamContainer} = this.$refs;

                if (this.navOpacity >= 1) {
                    navBackground.style.opacity = 1;
                    navTitle.style.opacity = 1;
                } else {
                    navBackground.style.opacity = 0;
                    navTitle.style.opacity = 0;
                }
            },
            handleResize() {
                const {navBar, navBackground, navTitle, extraContainer, streamContainer} = this.$refs;
                extraContainer.style.left = (streamContainer.offsetWidth - extraContainer.offsetWidth) + 'px';
            },
            navBarHeight() {
                return this.$refs.navBar.offsetHeight;
            },
            pageHeadHeight() {
                return this.$refs.pageHead.offsetHeight;
            },
            toggleDrawer() {
                this.isDrawerOpen = !this.isDrawerOpen;
                document.getElementsByTagName('html')[0].style.overflow = this.isDrawerOpen ? 'hidden' : 'unset';
            },
            closeDrawer() {
                this.isDrawerOpen = false;
                document.getElementsByTagName('html')[0].style.overflow = this.isDrawerOpen ? 'hidden' : 'unset';
            },
            toggleDarkMode() {
                this.isDarkMode = !this.isDarkMode;
                if (this.isDarkMode==true){
                    document.cookie = "night=1;path=/";
                    document.body.classList.add("night");
                } else {
                    document.cookie = "night=0;path=/";
                    document.body.classList.remove("night");
                }
            },
            debounce(func, wait, options) {
                let lastArgs,
                    lastThis,
                    maxWait,
                    result,
                    timerId,
                    lastCallTime

                let lastInvokeTime = 0
                let leading = false
                let maxing = false
                let trailing = true

                
                const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function')

                if (typeof func !== 'function') {
                    throw new TypeError('Expected a function')
                }
                function isObject(value) {
                    const type = typeof value
                    return value != null && (type === 'object' || type === 'function')
                }

                wait = +wait || 0
                if (isObject(options)) {
                    leading = !!options.leading
                    maxing = 'maxWait' in options
                    maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait
                    trailing = 'trailing' in options ? !!options.trailing : trailing
                }

                function invokeFunc(time) {
                    const args = lastArgs
                    const thisArg = lastThis

                    lastArgs = lastThis = undefined
                    lastInvokeTime = time
                    result = func.apply(thisArg, args)
                    return result
                }

                function startTimer(pendingFunc, wait) {
                    if (useRAF) {
                    root.cancelAnimationFrame(timerId)
                    return root.requestAnimationFrame(pendingFunc)
                    }
                    return setTimeout(pendingFunc, wait)
                }

                function cancelTimer(id) {
                    if (useRAF) {
                    return root.cancelAnimationFrame(id)
                    }
                    clearTimeout(id)
                }

                function leadingEdge(time) {
                    
                    lastInvokeTime = time
                    
                    timerId = startTimer(timerExpired, wait)
                    
                    return leading ? invokeFunc(time) : result
                }

                function remainingWait(time) {
                    const timeSinceLastCall = time - lastCallTime
                    const timeSinceLastInvoke = time - lastInvokeTime
                    const timeWaiting = wait - timeSinceLastCall

                    return maxing
                    ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
                    : timeWaiting
                }

                function shouldInvoke(time) {
                    const timeSinceLastCall = time - lastCallTime
                    const timeSinceLastInvoke = time - lastInvokeTime

                    
                    
                    
                    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
                    (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
                }

                function timerExpired() {
                    const time = Date.now()
                    if (shouldInvoke(time)) {
                    return trailingEdge(time)
                    }
                    
                    timerId = startTimer(timerExpired, remainingWait(time))
                }

                function trailingEdge(time) {
                    timerId = undefined

                    
                    
                    if (trailing && lastArgs) {
                    return invokeFunc(time)
                    }
                    lastArgs = lastThis = undefined
                    return result
                }

                function cancel() {
                    if (timerId !== undefined) {
                    cancelTimer(timerId)
                    }
                    lastInvokeTime = 0
                    lastArgs = lastCallTime = lastThis = timerId = undefined
                }

                function flush() {
                    return timerId === undefined ? result : trailingEdge(Date.now())
                }

                function pending() {
                    return timerId !== undefined
                }

                function debounced(...args) {
                    const time = Date.now()
                    const isInvoking = shouldInvoke(time)

                    lastArgs = args
                    lastThis = this
                    lastCallTime = time

                    if (isInvoking) {
                    if (timerId === undefined) {
                        return leadingEdge(lastCallTime)
                    }
                    if (maxing) {
                        
                        timerId = startTimer(timerExpired, wait)
                        return invokeFunc(lastCallTime)
                    }
                    }
                    if (timerId === undefined) {
                    timerId = startTimer(timerExpired, wait)
                    }
                    return result
                }
                debounced.cancel = cancel
                debounced.flush = flush
                debounced.pending = pending
                return debounced
                }

    },
    created() {
        window.addEventListener('scroll', this.handleScroll);
        window.addEventListener('resize', this.handleResize);
        window._nonDesktop = function () {
            let check = false;
            (function (a) {
                if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
            })(navigator.userAgent || navigator.vendor || window.opera);
            return check;
        };
        
        var night = document.cookie.replace(/(?:(?:^|.*;\s*)night\s*\=\s*([^;]*).*$)|^.*$/, "$1");
        if (night==""){
            if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
                
            }
        }else{
            
            if (night=="1") {
                this.toggleDarkMode();
            }
        }
    },
    mounted() {
        this.handleScroll();
        this.handleResize();
        this.mounted = true;

        
        
        

        document.querySelectorAll("table").forEach(function(elem){
            elem.classList.add("table-striped");
            elem.classList.add("table");
            elem.classList.add("table-responsive");
            elem.classList.add("table-hover");
        })

        
        spy();
        window.addEventListener('scroll', this.debounce(spy, 250, { 'maxWait': 250 }), false);
        
        
    },
    destroyed() {
        window.removeEventListener('scroll', this.handleScroll);
        window.removeEventListener('resize', this.handleResize);
    }
});



</script>
    </body>
</html>
